[PVFB] Make sure that framebuffer backend goes away when the domain
authorSteven Smith <ssmith@xensource.com>
Fri, 1 Dec 2006 12:03:15 +0000 (12:03 +0000)
committerSteven Smith <ssmith@xensource.com>
Fri, 1 Dec 2006 12:03:15 +0000 (12:03 +0000)
terminates, and that it cleans up its area of xenstore.

Tidy up argument parsing a little while I'm here.

Signed-off-by: Steven Smith <sos22@cam.ac.uk>
tools/xenfb/sdlfb.c
tools/xenfb/vncfb.c
tools/xenfb/xenfb.c
tools/xenfb/xenfb.h

index cc5f8d6f525e23656781902b311a0381cc37ba2a..6276c34659e2d30822bf5c0ed0eafd0d25ba4e46 100644 (file)
@@ -204,6 +204,7 @@ static int sdl_on_event(struct xenfb *xenfb, SDL_Event *event)
 static struct option options[] = {
        { "domid", 1, NULL, 'd' },
        { "title", 1, NULL, 't' },
+       { NULL }
 };
 
 int main(int argc, char **argv)
@@ -220,6 +221,7 @@ int main(int argc, char **argv)
        int do_quit = 0;
        int opt;
        char *endp;
+       int retval;
 
        while ((opt = getopt_long(argc, argv, "d:t:", options,
                                  NULL)) != -1) {
@@ -234,6 +236,8 @@ int main(int argc, char **argv)
                 case 't':
                        title = strdup(optarg);
                        break;
+               case '?':
+                       exit(1);
                 }
         }
         if (optind != argc) {
@@ -323,7 +327,11 @@ int main(int argc, char **argv)
                 if (do_quit)
                        break;
 
-               xenfb_poll(xenfb, &readfds);
+               retval = xenfb_poll(xenfb, &readfds);
+               if (retval == -2)
+                   xenfb_teardown(xenfb);
+               if (retval < 0)
+                   break;
        }
 
        xenfb_delete(xenfb);
index 2fc970e0cc967a8b50b7ace0f26a2b0b8e9d1233..49fc7306257468236dfb5d0e65098f216726b497 100644 (file)
@@ -253,6 +253,7 @@ static struct option options[] = {
        { "title", 1, NULL, 't' },
        { "unused", 0, NULL, 'u' },
        { "listen", 1, NULL, 'l' },
+       { NULL }
 };
 
 int main(int argc, char **argv)
@@ -272,6 +273,7 @@ int main(int argc, char **argv)
        int nfds;
        char portstr[10];
        char *endp;
+       int r;
 
        while ((opt = getopt_long(argc, argv, "d:p:t:u", options,
                                  NULL)) != -1) {
@@ -301,6 +303,8 @@ int main(int argc, char **argv)
                 case 'l':
                        listen = strdup(optarg);
                        break;
+               case '?':
+                       exit(1);
                 }
         }
         if (optind != argc) {
@@ -383,7 +387,11 @@ int main(int argc, char **argv)
                        break;
                }
 
-               xenfb_poll(xenfb, &readfds);
+               r = xenfb_poll(xenfb, &readfds);
+               if (r == -2)
+                   xenfb_teardown(xenfb);
+               if (r < 0)
+                   break;
        }
 
        rfbScreenCleanup(server);
index 82d31772df54e6f8fba2abaa5e72f05d6e35608c..496a365079800bcc504b3b820c969b9abc911621 100644 (file)
@@ -187,6 +187,17 @@ struct xenfb *xenfb_new(void)
        return NULL;
 }
 
+/* Remove the backend area in xenbus since the framebuffer really is
+   going away. */
+void xenfb_teardown(struct xenfb *xenfb_pub)
+{
+       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+
+       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
+       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
+}
+
+
 void xenfb_delete(struct xenfb *xenfb_pub)
 {
        struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
@@ -564,7 +575,7 @@ static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
        xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
 }
 
-static void xenfb_on_state_change(struct xenfb_device *dev)
+static int xenfb_on_state_change(struct xenfb_device *dev)
 {
        enum xenbus_state state;
 
@@ -572,6 +583,10 @@ static void xenfb_on_state_change(struct xenfb_device *dev)
 
        switch (state) {
        case XenbusStateUnknown:
+               /* There was an error reading the frontend state.  The
+                  domain has probably gone away; in any case, there's
+                  not much point in us continuing. */
+               return -1;
        case XenbusStateInitialising:
        case XenbusStateInitWait:
        case XenbusStateInitialised:
@@ -585,14 +600,17 @@ static void xenfb_on_state_change(struct xenfb_device *dev)
                xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
                xenfb_switch_state(dev, state);
        }
+       return 0;
 }
 
+/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
 int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
 {
        struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
        evtchn_port_t port;
        unsigned dummy;
        char **vec;
+       int r;
 
        if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
                port = xc_evtchn_pending(xenfb->evt_xch);
@@ -611,8 +629,11 @@ int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
        if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
                vec = xs_read_watch(xenfb->xsh, &dummy);
                free(vec);
-               xenfb_on_state_change(&xenfb->fb);
-               xenfb_on_state_change(&xenfb->kbd);
+               r = xenfb_on_state_change(&xenfb->fb);
+               if (r == 0)
+                       r = xenfb_on_state_change(&xenfb->kbd);
+               if (r == -1)
+                       return -2;
        }
 
        return 0;
index 007eb3b9b46ab1f297cff2a75d952ede9a345fca..c08d979b39286ae42dc824ec7f7084222f3c337b 100644 (file)
@@ -21,6 +21,7 @@ struct xenfb
 
 struct xenfb *xenfb_new(void);
 void xenfb_delete(struct xenfb *xenfb);
+void xenfb_teardown(struct xenfb *xenfb);
 
 int xenfb_attach_dom(struct xenfb *xenfb, int domid);